<script lang="ts" setup>
import {ref, onMounted, onUnmounted} from 'vue'
import * as echarts from 'echarts'
import {Refresh} from '@element-plus/icons-vue'
import {ElMessage} from 'element-plus'
import {
  reqDashboardData,
  reqMemberTypeDistribution,
  reqCourseSales,
  reqCourseRevenue,
  reqConsumptionTypeDistribution,
  reqConsumptionRanking,
  reqEquipmentStatusDistribution,
  reqEquipmentTypeDistribution,
  reqCoachGenderDistribution,
  reqCoachAgeDistribution
} from '@/api/statistics'
import type {
  ConsumptionRanking
} from '@/type/statistics'

// 状态定义
const loading = ref(false)
const dashboardData = ref<any[]>([])
const consumptionRanking = ref<ConsumptionRanking[]>([])

// 图表引用
const memberTypeChart = ref<HTMLElement>()
const courseSalesChart = ref<HTMLElement>()
const consumptionTypeChart = ref<HTMLElement>()
const equipmentChart = ref<HTMLElement>()
const coachChart = ref<HTMLElement>()

// 图表实例存储
const charts = new Map()

// 错误处理函数
const handleError = (error: any) => {
  loading.value = false
  ElMessage.error(error.message || '数据加载失败')
}

// 初始化仪表盘数据
const initDashboardData = async () => {
  try {
    loading.value = true
    const {data} = await reqDashboardData()
    dashboardData.value = [
      {label: '总会员数', value: data.totalMembers, icon: 'User'},
      {label: '总收入', value: `¥${data.totalRevenue.toFixed(2)}`, icon: 'Money'},
      {label: '课程数量', value: data.totalCourses, icon: 'Calendar'},
      {label: '设备数量', value: data.totalEquipment, icon: 'Tools'}
    ]
  } catch (error) {
    handleError(error)
  } finally {
    loading.value = false
  }
}

// 初始化会员类型分布图
const initMemberTypeChart = async () => {
  try {
    // 设置加载状态为true，表示正在加载数据
    loading.value = true

    // 从API获取会员类型分布的数据
    const {data} = await reqMemberTypeDistribution()

    // 初始化Echarts实例，使用ref绑定的DOM元素作为图表容器
    const chart = echarts.init(memberTypeChart.value)
    // 将图表实例存储到charts Map中，方便后续操作
    charts.set('memberType', chart)

    // 设置图表的配置项
    chart.setOption({
      // 提示框组件，用于显示数据信息
      tooltip: {
        // 触发类型为数据项图形触发
        trigger: 'item',
        // 自定义提示框内容格式
        formatter: '{a} <br/>{b}: {c} ({d}%)'
      },
      // 图例组件，用于显示图例
      legend: {
        // 图例垂直排列
        orient: 'vertical',
        // 图例位置在左侧
        left: 'left'
      },
      // 系列列表，定义图表的具体数据和样式
      series: [{
        // 系列名称
        name: '会员类型',
        // 图表类型为饼图
        type: 'pie',
        // 饼图半径为容器宽高的50%
        radius: '50%',
        // 数据项数组，每个数据项包含name和value
        data: data.map(item => ({
          name: item.name, // 数据项名称
          value: item.value // 数据项值
        }))
      }]
    })
  } catch (error) {
    // 捕获错误并调用错误处理函数
    handleError(error)
  } finally {
    // 无论是否成功，最后将加载状态设置为false
    loading.value = false
  }
}

// 初始化课程销量与收入图
const initCourseSalesChart = async () => {
  try {
    loading.value = true
    const [salesRes, revenueRes] = await Promise.all([
      reqCourseSales(),
      reqCourseRevenue()
    ])

    const chart = echarts.init(courseSalesChart.value)
    charts.set('courseSales', chart)

    const courseNames = salesRes.data.map(item => item.name)

    chart.setOption({
      tooltip: {trigger: 'axis'},
      legend: {
        data: ['销量', '收入']
      },
      grid: {
        left: '3%',
        right: '4%',
        bottom: '3%',
        containLabel: true
      },
      xAxis: [{
        type: 'category',
        data: courseNames,
        axisLabel: {
          rotate: 45,
          interval: 0
        }
      }],
      yAxis: [
        {
          type: 'value',
          name: '销量',
          position: 'left'
        },
        {
          type: 'value',
          name: '收入(元)',
          position: 'right'
        }
      ],
      series: [
        {
          name: '销量',
          type: 'bar',
          data: salesRes.data.map(item => item.salesCount)
        },
        {
          name: '收入',
          type: 'line',
          yAxisIndex: 1,
          data: revenueRes.data.map(item => item.revenue)
        }
      ]
    })
  } catch (error) {
    handleError(error)
  } finally {
    loading.value = false
  }
}

// 初始化消费类型分布图
const initConsumptionTypeChart = async () => {
  try {
    loading.value = true
    const {data} = await reqConsumptionTypeDistribution()
    const chart = echarts.init(consumptionTypeChart.value)
    charts.set('consumptionType', chart)

    chart.setOption({
      tooltip: {
        trigger: 'item',
        formatter: '{a} <br/>{b}: {c} ({d}%)'
      },
      legend: {
        orient: 'vertical',
        left: 'left'
      },
      series: [{
        name: '消费类型',
        type: 'pie',
        radius: ['40%', '70%'],
        avoidLabelOverlap: false,
        label: {
          show: false,
          position: 'center'
        },
        emphasis: {
          label: {
            show: true,
            fontSize: '20',
            fontWeight: 'bold'
          }
        },
        labelLine: {
          show: false
        },
        data: data.map(item => ({
          name: item.name,
          value: item.value
        }))
      }]
    })
  } catch (error) {
    handleError(error)
  } finally {
    loading.value = false
  }
}

// 初始化设备相关图表
const initEquipmentCharts = async () => {
  try {
    loading.value = true
    const [statusData, typeData] = await Promise.all([
      reqEquipmentStatusDistribution(),
      reqEquipmentTypeDistribution()
    ])

    const chart = echarts.init(equipmentChart.value)
    charts.set('equipment', chart)

    chart.setOption({
      tooltip: {
        trigger: 'item'
      },
      legend: {
        top: '5%',
        left: 'center'
      },
      series: [
        {
          name: '设备状态',
          type: 'pie',
          radius: ['20%', '40%'],
          center: ['25%', '50%'],
          data: statusData.data.map(item => ({
            name: item.name,
            value: item.value
          }))
        },
        {
          name: '设备类型',
          type: 'pie',
          radius: ['20%', '40%'],
          center: ['75%', '50%'],
          data: typeData.data.map(item => ({
            name: item.name,
            value: item.value
          }))
        }
      ]
    })
  } catch (error) {
    handleError(error)
  } finally {
    loading.value = false
  }
}

// 初始化教练相关图表
const initCoachCharts = async () => {
  try {
    loading.value = true
    const [genderRes, ageRes] = await Promise.all([
      reqCoachGenderDistribution(),
      reqCoachAgeDistribution()
    ])

    const chart = echarts.init(coachChart.value)
    charts.set('coach', chart)

    chart.setOption({
      tooltip: {
        trigger: 'item'
      },
      legend: {
        top: '5%',
        left: 'center'
      },
      grid: [{
        left: '50%',
        top: '20%',
        width: '45%',
        height: '70%',
        containLabel: true
      }],
      xAxis: [{
        gridIndex: 0,
        type: 'category',
        data: ageRes.data.map(item => item.ageGroup),
        axisLabel: {
          rotate: 30,
          interval: 0
        }
      }],
      yAxis: [{
        gridIndex: 0,
        type: 'value',
        name: '人数'
      }],
      series: [
        {
          name: '性别分布',
          type: 'pie',
          radius: ['20%', '40%'],
          center: ['25%', '50%'],
          data: genderRes.data.map(item => ({
            name: item.name,
            value: item.value
          }))
        },
        {
          name: '年龄分布',
          type: 'bar',
          xAxisIndex: 0,
          yAxisIndex: 0,
          data: ageRes.data.map(item => item.count)
        }
      ]
    })
  } catch (error) {
    handleError(error)
  } finally {
    loading.value = false
  }
}

// 初始化消费排行榜
const initConsumptionRanking = async () => {
  try {
    loading.value = true
    const {data} = await reqConsumptionRanking()
    consumptionRanking.value = data
  } catch (error) {
    handleError(error)
  } finally {
    loading.value = false
  }
}

// 窗口大小改变时重置图表大小
const handleResize = () => {
  charts.forEach(chart => {
    chart.resize()
  })
}

// 生命周期钩子
onMounted(async () => {
  await Promise.all([
    initDashboardData(),
    initMemberTypeChart(),
    initCourseSalesChart(),
    initConsumptionTypeChart(),
    initEquipmentCharts(),
    initCoachCharts(),
    initConsumptionRanking()
  ])

  window.addEventListener('resize', handleResize)
})

onUnmounted(() => {
  window.removeEventListener('resize', handleResize)
  charts.forEach(chart => {
    chart.dispose()
  })
})
</script>

<template>
  <div class="statistics-container">
    <!-- 加载状态 -->
    <el-loading v-model="loading" fullscreen/>

    <!-- 顶部数据卡片 -->
    <el-row :gutter="20" class="dashboard-cards">
      <el-col v-for="(item, index) in dashboardData" :key="index" :span="6">
        <el-card shadow="hover">
          <div class="dashboard-item">
            <el-icon :class="item.icon" :size="24">
              <component :is="item.icon"/>
            </el-icon>
            <div class="dashboard-info">
              <div class="value">{{ item.value }}</div>
              <div class="label">{{ item.label }}</div>
            </div>
          </div>
        </el-card>
      </el-col>
    </el-row>

    <!-- 会员相关统计 -->
    <el-row :gutter="20" class="chart-row">
      <el-col :span="12">
        <el-card>
          <template #header>
            <div class="card-header">
              <span>会员类型分布</span>
              <el-button :icon="Refresh" circle @click="initMemberTypeChart"/>
            </div>
          </template>
          <div ref="memberTypeChart" class="chart"></div>
        </el-card>
      </el-col>
      <el-col :span="12">
        <el-card>
          <template #header>
            <div class="card-header">
              <span>会员消费排行榜</span>
              <el-button :icon="Refresh" circle @click="initConsumptionRanking"/>
            </div>
          </template>
          <el-table :data="consumptionRanking" style="width: 100%; height: 400px">
            <el-table-column label="排名" type="index" width="80"/>
            <el-table-column label="会员姓名" prop="memberName"/>
            <el-table-column label="消费金额" prop="totalSpent">
              <template #default="scope">
                ¥{{ scope.row.totalSpent.toFixed(2) }}
              </template>
            </el-table-column>
          </el-table>
        </el-card>
      </el-col>
    </el-row>

    <!-- 课程和消费统计 -->
    <el-row :gutter="20" class="chart-row">
      <el-col :span="12">
        <el-card>
          <template #header>
            <div class="card-header">
              <span>课程销量与收入分析</span>
              <el-button :icon="Refresh" circle @click="initCourseSalesChart"/>
            </div>
          </template>
          <div ref="courseSalesChart" class="chart"></div>
        </el-card>
      </el-col>
      <el-col :span="12">
        <el-card>
          <template #header>
            <div class="card-header">
              <span>消费类型分布</span>
              <el-button :icon="Refresh" circle @click="initConsumptionTypeChart"/>
            </div>
          </template>
          <div ref="consumptionTypeChart" class="chart"></div>
        </el-card>
      </el-col>
    </el-row>

    <!-- 设备和教练统计 -->
    <el-row :gutter="20" class="chart-row">
      <el-col :span="12">
        <el-card>
          <template #header>
            <div class="card-header">
              <span>设备状态与类型分布</span>
              <el-button :icon="Refresh" circle @click="initEquipmentCharts"/>
            </div>
          </template>
          <div ref="equipmentChart" class="chart"></div>
        </el-card>
      </el-col>
      <el-col :span="12">
        <el-card>
          <template #header>
            <div class="card-header">
              <span>教练统计分析</span>
              <el-button :icon="Refresh" circle @click="initCoachCharts"/>
            </div>
          </template>
          <div ref="coachChart" class="chart"></div>
        </el-card>
      </el-col>
    </el-row>
  </div>
</template>

<style lang="scss" scoped>
.statistics-container {
  padding: 20px;

  .dashboard-cards {
    margin-bottom: 20px;
  }

  .dashboard-item {
    display: flex;
    align-items: center;

    .dashboard-info {
      margin-left: 20px;

      .value {
        font-size: 24px;
        font-weight: bold;
        color: #303133;
      }

      .label {
        color: #909399;
        font-size: 14px;
        margin-top: 4px;
      }
    }
  }

  .chart-row {
    margin-bottom: 20px;
  }

  .chart {
    height: 400px;
    width: 100%;
  }

  .card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
  }

  .ranking-row {
    margin-bottom: 20px;
  }
}
</style>
